package midas.mw.crt.jxta;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import javax.security.cert.CertificateException;

import sun.net.idn.Punycode;

import midas.mw.cfg.CfgError;
import midas.mw.cfg.CfgLogging;
import midas.mw.cfg.log.Logger;
import midas.mw.crt.jxta.Configuration;

import net.jxta.exception.PeerGroupException;
import net.jxta.id.IDFactory;
import net.jxta.peer.PeerID;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupFactory;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.platform.NetworkConfigurator;
import net.jxta.platform.NetworkManager;


/**
 * Class used for configuring the JXTA module of a node acting as a Central Node
 */
public class CentralNodeConfiguration implements Configuration
{		
	/**
     *  {@inheritDoc}
     */
	public NetworkManager startJxta(String name, String principal, String password, String ID, String publicIPAddress) 
	{
		CfgLogging.logEvent(CfgLogging.LOG_MCALL, Logger.COMPONENT_CRT, CfgLogging.SEV_DEBUG, "CentralNodeConfiguration.startJxta(" + name + ", " + principal +
				        	", " + password + ", " + ID + ")");			
		
		//If there is a peer Id configured, it will be used. If not, a new one will be created
		PeerID peerId 	= null;
		if (ID != null)
		{
			try {
				peerId =(PeerID) IDFactory.fromURI(new URI(ID));
			} catch (URISyntaxException use) {
				CfgError.errorReporting(CfgError.ERR_OPER, "CRT.CentralNodeConfiguration", CfgError.SEV_FATAL, 
						"CentralNodeConfiguration.startJxta(" + name + ", " + principal +
						", " + password + ", " + ID + "). Error starting the JXTA module: '" + 
						use.getMessage() + "'", null);
				return null;
			}
		}
		
		NetworkManager manager 				= null;
		NetworkConfigurator configurator 	= null;
		try {
			manager = new NetworkManager(NetworkManager.ConfigMode.SUPER, "MIDAS", new File(System.getProperty("JXTA_HOME")).toURI());			
		} catch (IOException ioe){ioe.printStackTrace();}
		
		manager.setConfigPersistent(true);
		try {
			configurator = manager.getConfigurator();
		} catch (IOException e) {
		    e.printStackTrace();
		}
		
		// Does a local peer configuration exist?
		if (configurator.exists()) 
		{
			
			File LocalConfig = new File(configurator.getHome(), "PlatformConfig");
		    try {		   
		         configurator.load(LocalConfig.toURI());
		    } catch (IOException ex) {
		         ex.printStackTrace();
		    } catch (CertificateException ce) {
		         // An issue with the existing peer certificate has been encountered
		         ce.printStackTrace();
		    }
		} 
		else 
		{
			configurator.setName(name);
			configurator.setPrincipal(principal);
			configurator.setPassword(password);	
			configurator.setDescription("Central node");
			
			try {
				configurator.setInfrastructureID((PeerGroupID )IDFactory.fromURI(new URI(MIDAS_GROUP_ID)));
				configurator.setInfrastructureName("MIDAS NETWORK");  
				//sconfigurator.setInfrastructureDescriptionStr("Nodes running in the midas network");
			}catch (URISyntaxException use) {            
	        	CfgError.errorReporting(CfgError.ERR_OPER, Logger.COMPONENT_CRT, CfgError.SEV_FATAL, 
						"JxtaModule.createGroup(). The URI used to form the group could not be parsed: '" +
						use.getMessage() + "'", null);
	        }
			
			URI seedingURI = new File(CENTRAL_NODES_FILE).toURI();  
			configurator.addRdvSeedingURI(seedingURI);
			configurator.addRelaySeedingURI(seedingURI);
			configurator.setUseOnlyRelaySeeds(true);
			configurator.setUseOnlyRendezvousSeeds(true);
			
			if (!publicIPAddress.equals(""))
			{
				configurator.setTcpInterfaceAddress(publicIPAddress);
				configurator.setHttpInterfaceAddress(publicIPAddress);
				configurator.setHttpPublicAddress(publicIPAddress + ":9700", true);
				configurator.setTcpPublicAddress(publicIPAddress + ":9701", true);
				configurator.setTcpStartPort(-1);
				configurator.setTcpEndPort(-1);
			}
		    try {		         
		         configurator.save();		         
		    } catch (IOException ex) {
		         ex.printStackTrace();		         
		    }
		}
		
		return manager;
	}
}